import Constants from "../libs/Constants";
import Helper from "../libs/HelperMgr";
import CameraManager from "./CameraManager";
import GameManager from "./GameManager";
import Ground from "./Ground";
import Player from "./Player";

const { ccclass, property } = cc._decorator;

@ccclass
export default class JoystickLeft extends cc.Component {

 
  private player: cc.Node = null;


  @property({
    type: cc.Node,
    displayName: 'Dot',
    tooltip: '摇杆操纵点',
  })
  dot: cc.Node = null;

  @property({
    type: cc.Node,
    displayName: 'Ring',
    tooltip: '摇杆背景节点',
  })
  ring: cc.Node = null;



  @property({
    tooltip: 'curDir',
  })
  curDir = ""

  @property({
    tooltip: 'faceTo',
  })
  faceTo = "K"

  @property({
    displayName: 'Move Dir',
    tooltip: '移动方向',
  })
  moveDir: cc.Vec2 = new cc.Vec2(0, 1);

  _speedType = Constants.SpeedType.STOP;

  @property({
    type: cc.Integer,
    tooltip: '停止时速度',
  })
  stopSpeed = 0;

  @property({
    type: cc.Integer,
    tooltip: '正常速度',
  })
  normalSpeed = 200;

  @property({
    type: cc.Integer,
    tooltip: '最快速度',
  })
  fastSpeed = 200;

  @property({
    type: cc.Enum(Constants.JoystickType),
    displayName: 'joystickType',
    tooltip: 'Touch Type',
  })
  joystickType = Constants.JoystickType.FOLLOW;

  @property({
    type: cc.Enum(Constants.DirectionType),
    displayName: 'directionType',
    tooltip: '方向类型',
  })
  directionType = Constants.DirectionType.FOUR;

  @property({
    tooltip: '摇杆所在位置',
  })
  _stickPos = null;

  @property({
    tooltip: '触摸位置',
  })
  _touchLocation = null;

  _radius = null;

  // from self
  _moveSpeed: number = 0;
  _movePosi: cc.Vec2 = null;



  //playe getPosition
  playerPos: cc.Vec2 = null;

  onLoad() {
    this.player = GameManager.instace.player;

    this._radius = this.ring.width / 2;
    this._initTouchEvent();
    if (this.joystickType === Constants.JoystickType.FOLLOW) {
      this.node.opacity = 0;
    }


  }



  _initTouchEvent() {
    this.node.on(cc.Node.EventType.TOUCH_START, this._touchStartEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_END, this._touchEndEvent, this);
    this.node.on(cc.Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);
  }

  _touchStartEvent(event) {
    const touchPos = this.node.convertToNodeSpaceAR(event.getLocation());

    if (this.joystickType === Constants.JoystickType.FIXED) {
      this._stickPos = this.ring.getPosition();

      // 触摸点与圆圈中心的距离
      const distance = touchPos.sub(this.ring.getPosition()).mag();

      // 手指在圆圈内触摸,控杆跟随触摸点
      this._radius > distance && this.dot.setPosition(touchPos);

    } else if (this.joystickType === Constants.JoystickType.FOLLOW) {

      // 记录摇杆位置，给 touch move 使用
      this._stickPos = touchPos;
      this.node.opacity = 255;
      this._touchLocation = event.getLocation();

      // 更改摇杆的位置
      this.ring.setPosition(touchPos);
      this.dot.setPosition(touchPos);
    }
    this._isMove = true;
  }

  _touchMoveEvent(event) {
    // 如果 touch start 位置和 touch move 相同，禁止移动
    if (this.joystickType === Constants.JoystickType.FOLLOW && this._touchLocation === event.getLocation()) {
      return false;
    }

    // 以圆圈为锚点获取触摸坐标
    const touchPos = this.ring.convertToNodeSpaceAR(event.getLocation());
    const distance = touchPos.mag();

    // 由于摇杆的 postion 是以父节点为锚点，所以定位要加上 touch start 时的位置
    const posX = this._stickPos.x + touchPos.x;
    const posY = this._stickPos.y + touchPos.y;

    // 归一化
    const p = cc.v2(posX, posY).sub(this.ring.getPosition()).normalize();

    let speedType;

    if (this._radius > distance) {
      this.dot.setPosition(cc.v2(posX, posY));

      speedType = Constants.SpeedType.NORMAL;
    } else {
      // 控杆永远保持在圈内，并在圈内跟随触摸更新角度
      const x = this._stickPos.x + p.x * this._radius;
      const y = this._stickPos.y + p.y * this._radius;
      this.dot.setPosition(cc.v2(x, y));

      speedType = Constants.SpeedType.FAST;
    }

    this.onTouchMove(event, { speedType: speedType, moveDistance: p })
  }

  _touchEndEvent(event) {
    this.dot.setPosition(this.ring.getPosition());
    if (this.joystickType === Constants.JoystickType.FOLLOW) {
      this.node.opacity = 0;
    }

    this.onTouchEnd(event, { speedType: Constants.SpeedType.STOP })

    this._isMove = false;
  }


  move() {
    let newPos = this.getfwinfo(this.moveDir);
    let nowmovespeed = this._moveSpeed / 120
    let p = this.player.getPosition();

    switch (newPos) {
      case 'W':
        p.y += nowmovespeed; break;
      case 'S':
        p.y -= nowmovespeed; break;
      case 'A':
        p.x -= nowmovespeed; break;
      case 'D':
        p.x += nowmovespeed; break;
      case 'WA':
        p.y += nowmovespeed; p.x -= nowmovespeed; break;
      case 'SA':
        p.y -= nowmovespeed; p.x -= nowmovespeed; break;
      case 'WD':
        p.y += nowmovespeed; p.x += nowmovespeed; break;
      case 'SD':
        p.y -= nowmovespeed; p.x += nowmovespeed; break;
    }

    if(Helper.PointInPoly(p,GameManager.instace.ground.getComponent(Ground).points)){
      this.player.setPosition(p) ;
    }

  }



  onTouchMove(event, data) {
    this._speedType = data.speedType;
    this.moveDir = data.moveDistance;
    //获取移动方位
    let newPos = this.getfwinfo(this.moveDir);
    // console.log(newPos);
    //判断移动方位跟之前的方位是否发生变化，如果发生变化，切切换动画
    if (this.faceTo != newPos) {
      switch (newPos) {
        case 'K':
        // this.toStand(); break;
        case 'W':
        // this.toWalk(1); break;
        case 'S':
        // this.toWalk(5); break;
        case 'A':
          // this.toWalk(7); break;
        case 'D':
          // this.toWalk(3); break;
        case 'WA':
        // this.toWalk(0); break;
        case 'SA':
        // this.toWalk(6); break;
        case 'WD':
        // this.toWalk(2); break;
        case 'SD':
        // this.toWalk(4); break;
      }
    }
  }

  //播放移动动画
  toWalk(dir) {
    if (dir == this.curDir) return;
   
  }

  private _isMove: boolean = false;

  update(dt: number) {

    switch (this._speedType) {
      case Constants.SpeedType.STOP:
        this._moveSpeed = this.stopSpeed;
        break;
      case Constants.SpeedType.NORMAL:
        this._moveSpeed = this.normalSpeed;
        break;
      case Constants.SpeedType.FAST:
        this._moveSpeed = this.fastSpeed;
        break;
      default:
        break;
    }
    this.move();

  }


  onTouchEnd(event, data) {
    this._speedType = data.speedType;

    if (event.type == "touchcancel" && this._movePosi) {
      this.player.setPosition(this._movePosi)
    }
  }




  //获取方位信息
  getfwinfo(data) {
    var CurrentDire = 'K'
    var currentAngle = this.getCalculaAngle(data);
    if (currentAngle <= 22.5 && currentAngle >= 0 || currentAngle <= 360 && currentAngle >= 337.5)//0;左
      CurrentDire = "A";
    else if (currentAngle <= 67.5 && currentAngle >= 22.5)//45;左上
      CurrentDire = "WA";
    else if (currentAngle <= 112.5 && currentAngle >= 67.5)//90;上
      CurrentDire = "W";
    else if (currentAngle <= 157.5 && currentAngle >= 112.5)//135;右上
      CurrentDire = "WD";
    else if (currentAngle <= 202.5 && currentAngle >= 157.5)//180;右
      CurrentDire = "D";
    else if (currentAngle <= 247.5 && currentAngle >= 202.5)//225;右下
      CurrentDire = "SD";
    else if (currentAngle <= 292.5 && currentAngle >= 247.5)//270;下
      CurrentDire = "S";
    else if (currentAngle <= 337.5 && currentAngle >= 292.5)//315;左下
      CurrentDire = "SA";
    return CurrentDire

  }


  //角度转换180
  getCalculaAngle(data) {
    var currentAngleX = data.x * 90 + 90;//X轴 当前角度
    var currentAngleY = data.y * 90 + 90;//Y轴 当前角度
    if (currentAngleY < 90) {
      if (currentAngleX < 90) {
        return 270 + currentAngleY;
      }
      else if (currentAngleX > 90) {
        return 180 + (90 - currentAngleY);
      }
    }
    return currentAngleX;
  }
}
